package com.boot.web.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.boot.constant.Constants;
import com.boot.utils.CertHttpUtil;
import com.boot.utils.PayUtil;
import com.boot.utils.Units;
import com.boot.web.dao.AccountDao;
import com.boot.web.dao.AccountRecordDao;
import com.boot.web.dto.AlipayFundTransUniTransferDTO;
import com.boot.web.dto.BusinessParamsDTO;
import com.boot.web.dto.PayeeInfoDTO;
import com.boot.web.entity.Account;
import com.boot.web.entity.AccountRecord;
import com.github.pagehelper.PageInfo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.boot.communal.paging.InitPaging;
import com.boot.communal.response.ResponseServer;
import com.boot.web.entity.Withdrawal;
import com.boot.web.service.WithdrawalService;

/**
 * 银行卡提现记录控制器
 * @author 【zhouJie】
 * @date 2021-11-14 18:16:34
 */
@RestController
@RequestMapping("/withdrawal")
public class WithdrawalController {

    @Autowired
    private WithdrawalService withdrawalService;

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private AccountRecordDao accountRecordDao;

    @PostMapping("/save")
    public ResponseServer save(Withdrawal withdrawal) {
        return ResponseServer.success("添加成功", withdrawalService.save(withdrawal));
    }

    @PutMapping("/update")
    public ResponseServer update(Withdrawal withdrawal) throws AlipayApiException {
        Withdrawal oldW = withdrawalService.getById(withdrawal.getId());
        Account account = accountDao.queryAccountByUserId(withdrawal.getUserId());
        if("1".equals(withdrawal.getStatus()) && "0".equals(oldW.getStatus())){
            // 可以提现
            if("0".equals(withdrawal.getArrivalType())){
                // 到账微信
                Map<String, Object> map = new HashMap<>();
                map.put("openid", withdrawal.getOpenId());
                map.put("money", withdrawal.getActualAmount().doubleValue()); //实际到账的钱
                map.put("outTradeNo", withdrawal.getOrderNo());
                Map<String, Object> maps = merchantToPersonal_wxpay(map);
                if (maps.get("result_code").equals("SUCCESS")) {
                    System.err.println("---------- 商户付款到个人零钱成功!!!");
                    withdrawal.setInfo("成功");
                    withdrawalService.update(withdrawal);
                }else{
                    withdrawal.setStatus("2");
                    withdrawal.setInfo(maps.get("meg").toString());
                    withdrawalService.update(withdrawal);
                    // 提余额
                    if("0".equals(withdrawal.getBalanceType())){
                        account.setVoucherBalance(account.getVoucherBalance().add(withdrawal.getAmount()));
                    }
                    // 提拼团
                    else if("1".equals(withdrawal.getBalanceType())){
                        account.setCollageBalance(account.getCollageBalance().add(withdrawal.getAmount()));
                    }
                    // 提共享
                    else if("2".equals(withdrawal.getBalanceType())){
                        account.setShareBalance(account.getShareBalance().add(withdrawal.getAmount()));
                    }
                    accountDao.update(account);
                    //添加记录
                    AccountRecord ar = new AccountRecord();
                    ar.setOutUserId(withdrawal.getUserId());
                    ar.setUpdateTime(new Date());
                    if("0".equals(withdrawal.getBalanceType())){
                        ar.setType("0");
                        ar.setNowAmount(account.getVoucherBalance());
                        ar.setInfo("余额提现-退回");
                    }
                    // 提拼团
                    else if("1".equals(withdrawal.getBalanceType())){
                        ar.setType("8");
                        ar.setNowAmount(account.getCollageBalance());
                        ar.setInfo("拼团余额提现-退回");
                    }
                    // 提共享
                    else if("2".equals(withdrawal.getBalanceType())){
                        ar.setType("10");
                        ar.setNowAmount(account.getShareBalance());
                        ar.setInfo("共享余额提现-退回");
                    }
                    ar.setAmount(withdrawal.getAmount());
                    ar.setSign("1");
                    ar.setOrderNo(withdrawal.getOrderNo());
                    accountRecordDao.save(ar);
                }
            }else if("1".equals(withdrawal.getArrivalType())){
                // 到账支付宝
                Map<String, String> map = merchantToPersonal_alipay(withdrawal.getOrderNo(), withdrawal.getAlipayUserId());
                if("1".equals(map.get("sign"))){
                    withdrawal.setInfo(map.get("info"));
                    withdrawalService.update(withdrawal);
                }else{
                    withdrawal.setStatus("2");
                    withdrawal.setInfo(map.get("info"));
                    withdrawalService.update(withdrawal);
                    // 提余额
                    if("0".equals(withdrawal.getBalanceType())){
                        account.setVoucherBalance(account.getVoucherBalance().add(withdrawal.getAmount()));
                    }
                    // 提拼团
                    else if("1".equals(withdrawal.getBalanceType())){
                        account.setCollageBalance(account.getCollageBalance().add(withdrawal.getAmount()));
                    }
                    // 提共享
                    else if("2".equals(withdrawal.getBalanceType())){
                        account.setShareBalance(account.getShareBalance().add(withdrawal.getAmount()));
                    }
                    accountDao.update(account);
                    //添加记录
                    AccountRecord ar = new AccountRecord();
                    ar.setOutUserId(withdrawal.getUserId());
                    ar.setUpdateTime(new Date());
                    if("0".equals(withdrawal.getBalanceType())){
                        ar.setType("0");
                        ar.setNowAmount(account.getVoucherBalance());
                        ar.setInfo("余额提现-退回");
                    }
                    // 提拼团
                    else if("1".equals(withdrawal.getBalanceType())){
                        ar.setType("8");
                        ar.setNowAmount(account.getCollageBalance());
                        ar.setInfo("拼团余额提现-退回");
                    }
                    // 提共享
                    else if("2".equals(withdrawal.getBalanceType())){
                        ar.setType("10");
                        ar.setNowAmount(account.getShareBalance());
                        ar.setInfo("共享余额提现-退回");
                    }
                    ar.setAmount(withdrawal.getAmount());
                    ar.setSign("1");
                    ar.setOrderNo(withdrawal.getOrderNo());
                    accountRecordDao.save(ar);
                }
            }
        }else if("2".equals(withdrawal.getStatus()) && "0".equals(oldW.getStatus())){
            // 发起退款
            if("".equals(withdrawal.getInfo())){
                withdrawal.setInfo("后台修改 - 退回账户");
            }
            withdrawalService.update(withdrawal);
            // 提余额
            if("0".equals(withdrawal.getBalanceType())){
                account.setVoucherBalance(account.getVoucherBalance().add(withdrawal.getAmount()));
            }
            // 提拼团
            else if("1".equals(withdrawal.getBalanceType())){
                account.setCollageBalance(account.getCollageBalance().add(withdrawal.getAmount()));
            }
            // 提共享
            else if("2".equals(withdrawal.getBalanceType())){
                account.setShareBalance(account.getShareBalance().add(withdrawal.getAmount()));
            }
            accountDao.update(account);
            //添加记录
            AccountRecord ar = new AccountRecord();
            ar.setOutUserId(withdrawal.getUserId());
            ar.setUpdateTime(new Date());
            if("0".equals(withdrawal.getBalanceType())){
                ar.setType("0");
                ar.setNowAmount(account.getVoucherBalance());
                ar.setInfo("余额提现-退回");
            }
            // 提拼团
            else if("1".equals(withdrawal.getBalanceType())){
                ar.setType("8");
                ar.setNowAmount(account.getCollageBalance());
                ar.setInfo("拼团余额提现-退回");
            }
            // 提共享
            else if("2".equals(withdrawal.getBalanceType())){
                ar.setType("10");
                ar.setNowAmount(account.getShareBalance());
                ar.setInfo("共享余额提现-退回");
            }
            ar.setAmount(withdrawal.getAmount());
            ar.setSign("1");
            ar.setOrderNo(withdrawal.getOrderNo());
            accountRecordDao.save(ar);
        }else{
            // 不做处理
            return ResponseServer.error("修改后的提现状态不符合规范!!!");
        }
        return ResponseServer.success("修改成功", withdrawalService.update(withdrawal));
    }

    @DeleteMapping("/delete/{id}")
    public ResponseServer delete(@PathVariable Integer id) {
        return ResponseServer.success("删除成功", withdrawalService.delete(id));
    }

    @DeleteMapping("/batchDelete/{ids}")
    public ResponseServer batchDelete(@PathVariable Integer[] ids) {
        return ResponseServer.success("批量删除成功", withdrawalService.batchDelete(ids));
    }

    @GetMapping("/getPageList")
    public ResponseServer getPageList(@RequestParam Map<String, Object> params) {
        InitPaging.init(params);
        return ResponseServer.success(new PageInfo(withdrawalService.getPageList(params)));
    }

    @GetMapping("/getAll")
    public ResponseServer getAll() {
        return ResponseServer.success(withdrawalService.getAll());
    }

    @GetMapping("/getById/{id}")
    public ResponseServer getById(@PathVariable Integer id) {
        return ResponseServer.success(withdrawalService.getById(id));
    }

    public static Map<String, Object> merchantToPersonal_wxpay(Map<String, Object> map) {
        Map<String, Object> maps = new HashMap<>();
        // openid
        String openId = map.get("openid").toString();
        // 付款ip
        String ip ="39.105.107.98";  // 正式 39.105.107.98 测试 123.60.20.4
        // 金额
        String money = map.get("money").toString();
        if (StringUtils.isNotBlank(openId) && StringUtils.isNotBlank(money)) {
            // 随机字符串
            String nonceStr = Units.getRandomStringByLength(32);
            // 是否检查真实姓名
            String checkName = "NO_CHECK";
            String re_user_name = "周杰";
            // 等待确认转账金额,ip,openid的来源
            double mo = (Double.parseDouble(money)) * 100;
            String amountFen = String.valueOf((int) mo);
            String spbill_create_ip = ip;
            String partner_trade_no = map.get("outTradeNo").toString();
            String orderCode = partner_trade_no.substring(0,6);
            String orderCodes = partner_trade_no.substring(0,3);
            // appid
            String appid = Constants.app_appid;
            // 备注
            String remarks = "蜜蜂嗡嗡提现: ";
            // machid
            String mch_id = "1516343511"; // Constants.wxspMch_id;
            // 描述
            String desc = remarks + mo / 100 + "元";
            // 构造签名的map
            SortedMap<String, String> parameters = new TreeMap<>();
            // 参数：开始生成第一次签名
            parameters.put("mch_appid", appid);
            parameters.put("mchid", mch_id);
            parameters.put("partner_trade_no", partner_trade_no);
            parameters.put("nonce_str", nonceStr);
            parameters.put("openid", openId);
            parameters.put("check_name", checkName);
            parameters.put("re_user_name", re_user_name);
            parameters.put("amount", amountFen);
            parameters.put("spbill_create_ip", spbill_create_ip);
            parameters.put("desc", desc);
            // 调用逻辑传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            String stringA = Units.formatUrlMap(parameters,false,false);
            String sign = null;
            try {
                // 获取签名
                String jjlkey = "jiajiani201901092228987456123012";
                sign = PayUtil.WXMD5(stringA + "&key=" + jjlkey).toUpperCase();
            } catch (Exception e) {
                e.printStackTrace();
            }
            parameters.put("sign", sign);
            /**
             * 封装请求数据
             */
            // 将参数 编写XML格式
            StringBuffer paramBuffer = new StringBuffer();
            paramBuffer.append("<xml>");
            paramBuffer.append("<mch_appid>" + parameters.get("mch_appid") + "</mch_appid>");
            paramBuffer.append("<mchid>" + parameters.get("mchid")+ "</mchid>");
            paramBuffer.append("<nonce_str>" + parameters.get("nonce_str")+ "</nonce_str>");
            paramBuffer.append("<partner_trade_no>" + parameters.get("partner_trade_no") + "</partner_trade_no>");
            paramBuffer.append("<openid>" + parameters.get("openid")+ "</openid>");
            paramBuffer.append("<check_name>" +parameters.get("check_name") + "</check_name>");
            paramBuffer.append("<re_user_name>" + parameters.get("re_user_name") + "</re_user_name>");
            paramBuffer.append("<amount>" + parameters.get("amount") + "</amount>");
            paramBuffer.append("<desc>" + parameters.get("desc") + "</desc>");
            paramBuffer.append("<spbill_create_ip>" + parameters.get("spbill_create_ip") + "</spbill_create_ip>");
            paramBuffer.append("<sign>" + parameters.get("sign") + "</sign>");
            paramBuffer.append("</xml>");
            // 将请求参数转换成String类型
            //String requestXML =PayForUtil.getRequestXml(parameters);
            System.err.println(paramBuffer.toString());
            CertHttpUtil cre = new CertHttpUtil();
            // 发送请求(POST)(获得数据包ID)(这有个注意的地方 如果不转码成ISO8859-1则会告诉你body不是UTF8编码
            // 就算你改成UTF8编码也一样不好使 所以修改成ISO8859-1)
            try {
                Map<String, String> transferMap = Units.doXMLParse(cre.postData(Constants.MerchantToPersonalURL,
                        new String(paramBuffer.toString().getBytes(), "UTF-8")).trim());
                System.err.println("返回状态:" + transferMap.get("return_code"));
                System.err.println("微信订单号:" + transferMap.get("payment_no"));
                System.err.println("商户订单号:" + transferMap.get("partner_trade_no"));
                System.err.println("业务结果:" + transferMap.get("result_code"));
                System.err.println("错误代码:" + transferMap.get("err_code"));
                System.err.println("错误代码描述:" + transferMap.get("err_code_des"));
                System.err.println("付款成功时间:" + transferMap.get("payment_time"));
                if (transferMap.get("return_code").equals("SUCCESS")) {
                    //if (transferMap.get("result_code").equals("SUCCESS")) {
                        // 成功需要进行的逻辑操作，
                        maps.put("result_code", "SUCCESS");
                        maps.put("meg", "付款成功");
                        System.err.println("========== >>>>>>>>>> 企业付款到零钱成功");
                    //} else {
                        //maps.put("result_code", "err");
                        //maps.put("meg", transferMap.get("err_code_des"));
                        //System.err.println("==========0 >>>>>>>>>> 企业付款到零钱失败"+transferMap.get("err_code_des"));
                    //}
                }else{
                    maps.put("result_code", "err");
                    maps.put("meg", transferMap.get("err_code_des"));
                    System.err.println("==========1 >>>>>>>>>> 企业付款到零钱失败"+transferMap.get("err_code_des"));
                }

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (JDOMException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else {
            maps.put("result_code", "err");
            maps.put("meg","参数不对");
            System.err.println("企业付款到零钱失败");
        }
        return maps;
    }

    public static Map<String, String> merchantToPersonal_alipay(String orderNo, String alipayUserId) throws AlipayApiException {
        // 封装请求信息
        AlipayFundTransUniTransferDTO dto = new AlipayFundTransUniTransferDTO();
        dto.setBizScene("DIRECT_TRANSFER"); // 业务场景
        List<BusinessParamsDTO> bpList = new ArrayList<>();
        BusinessParamsDTO bp = new BusinessParamsDTO();
        bp.setPayer_show_name("蜜蜂嗡嗡实业(深圳)有限公司");
        bpList.add(bp);
        dto.setBusinessParams(JSONArray.fromObject(bpList).toString()); // 转账业务请求的扩展参数
        dto.setOrderTitle("支付宝提现"); // 转账业务的标题
        dto.setOutBizNo(orderNo); // 提现号
        List<PayeeInfoDTO> piList = new ArrayList<>();
        PayeeInfoDTO pi = new PayeeInfoDTO();
        pi.setIdentity(alipayUserId);
        pi.setIdentity_type("ALIPAY_USER_ID");
        pi.setName(""); // 支付宝个人的真实姓名，可以不填写
        piList.add(pi);
        dto.setPayeeInfo(JSONArray.fromObject(piList).toString()); // 收款方信息
        dto.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码
        dto.setRemark("支付宝提现"); // 业务备注
        dto.setTransAmount(String.valueOf(1)); // 订单金额
        // 调用RSA签名方式
        AlipayClient alipayClient = new DefaultAlipayClient(Constants.aliPay_gatewayUrl, Constants.aliPay_app_id,
                Constants.merchant_private_key, Constants.aliPay_format, Constants.aliPay_charset_gbk,
                Constants.aliPay_public_key, Constants.aliPay_sign_type);
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        request.setBizContent(JSONObject.fromObject(dto).toString());
        AlipayFundTransUniTransferResponse response = alipayClient.execute(request);
        System.err.println("支付宝付款到个人账户返回的数据： AlipayFundTransUniTransferResponse： " + response);
        Map<String, String> map = new HashMap<>();
        if(response.isSuccess()){
            System.err.println("支付宝付款到个人账户 - 调用成功");
            map.put("info", response.getOrderId());
            map.put("sign", "1");
        } else {
            System.err.println("支付宝付款到个人账户 - 调用失败");
            map.put("info", response.getMsg());
            map.put("sign", "0");
        }
        return map;
    }

}
